using UnityEngine;

namespace NL.Advanced
{
    public class TargetCollectorCustom : TargetCollectorBase
    {
        private static readonly Collider[] _colliders = new Collider[100];

        [SerializeField] private LayerMask _CheckLayerMask;

        protected override void Awake()
        {
            _Collider = gameObject.GetComponent<Collider>();
        }

        public void Collect()
        {
            if (_Collider == null)
            {
                return;
            }

            if (_Collider is SphereCollider)
            {
                CollectBySphere(_Collider as SphereCollider);
            }
            else if (_Collider is BoxCollider)
            {
                CollectByBox(_Collider as BoxCollider);
            }
            else if (_Collider is CapsuleCollider)
            {
                CollectByCapsule(_Collider as CapsuleCollider);
            }
        }

        #region overlap

        private void CollectBySphere(SphereCollider sphereCollider)
        {
            var trans = sphereCollider.transform;
            var pos = trans.position;
            var radius = trans.lossyScale.x * sphereCollider.radius;
            var hitCount = Physics.OverlapSphereNonAlloc(pos, radius, _colliders, _CheckLayerMask);

            Fill(hitCount);
        }

        private void CollectByBox(BoxCollider boxCollider)
        {
            var trans = boxCollider.transform;
            var scale = trans.lossyScale;
            var pos = trans.position + boxCollider.center;
            var boxSize = boxCollider.size;
            var size = new Vector3(scale.x * boxSize.x, scale.y * boxSize.y, scale.z * boxSize.z);
            var halfSize = size / 2;
            var hitCount = Physics.OverlapBoxNonAlloc(pos, halfSize, _colliders, trans.rotation, _CheckLayerMask);

            Fill(hitCount);
        }

        private void CollectByCapsule(CapsuleCollider capsuleCollider)
        {
            var trans = capsuleCollider.transform;
            var center = capsuleCollider.center;
            var scale = trans.lossyScale;
            var height = scale.y * capsuleCollider.height;
            var up = trans.up;
            var pos = trans.position;
            var halfHeight = height / 2;
            var point1 = pos + center - up * halfHeight;
            var point2 = pos + center + up * halfHeight;
            var radius = scale.x * capsuleCollider.radius;
            var hitCount = Physics.OverlapCapsuleNonAlloc(point1, point2, radius, _colliders, _CheckLayerMask);

            Fill(hitCount);
        }

        #endregion

        private void Fill(int count)
        {
            if (count > _colliders.Length)
            {
                Debug.LogError($"Target collector custom collider count error {count}");
            }

            _All.Clear();

            for (int i = 0; i < count; ++i)
            {
                Add(_colliders[i]);
            }
        }
    }
}

